﻿package com.media.controllers{

	import flash.utils.Timer;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.TimerEvent;
	import flash.events.NetStatusEvent;
	import flash.events.ProgressEvent;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import com.events.MediaEvent;

	public class FLVController extends MediaController {
		private var _stream_ns:NetStream;
		private var _connection_nc:NetConnection;
		private var _videoEnded:Boolean;
		private var _loadTimer:Timer;

		override public function loadMedia(pFileURL:String):void {
			super.loadMedia(pFileURL);
			_connection_nc = new NetConnection();
			try {
				_connection_nc.connect(null);
				_stream_ns = new NetStream(_connection_nc);
				_stream_ns.addEventListener(NetStatusEvent.NET_STATUS,onNetStatus, false, 0, true);
				_stream_ns.client = this;
				applySoundTransform();
				dispatchEvent(new MediaEvent(MediaEvent.LOAD));
				startMedia();
			} catch (e:Error) {
			}
		}
		
		public function onCuePoint(pData:Object):void {
		}
		
		public function onMetaData(pData:Object):void {
			if (pData.duration > 0) {
				mediaDuration = pData.duration;
			}
			dispatchEvent(new MediaEvent(MediaEvent.METADATA,mediaPosition, mediaDuration, pData.width, pData.height));
		}
		
		override public function startMedia():void {
			_videoEnded = false;
			if (paused) {
				_stream_ns.resume();
			} else {
				try {
					_stream_ns.play(mediaFile);
					if (_stream_ns.bytesLoaded != _stream_ns.bytesTotal&& _stream_ns.bytesTotal > 0) {
						_loadTimer = new Timer(500, 0);
						_loadTimer.addEventListener(TimerEvent.TIMER,assessLoad, false, 0, true);
						_loadTimer.start();
					}
				} catch (e:Error) {
				}
			}
			super.startMedia();
		}
		
		private function assessLoad(pEvent:TimerEvent):void {
			dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS,false, false, _stream_ns.bytesLoaded, _stream_ns.bytesTotal));
			if (_stream_ns.bytesLoaded == _stream_ns.bytesTotal) {
				dispatchEvent(new Event(Event.COMPLETE));
				_loadTimer.removeEventListener(TimerEvent.TIMER, assessLoad);
				_loadTimer.stop();
			}
		}
		
		override public function seek(pOffset:Number):void {
			_videoEnded = false;
			var pTime:int = Math.round(pOffset*1000)/1000;
			_stream_ns.seek(pTime);
			super.seek(pTime);
		}
		
		override public function stopMedia():void {
			_stream_ns.seek(0);
			_stream_ns.pause();
			super.stopMedia();
		}
		
		override public function pauseMedia(pPause:Boolean):void {
			if (pPause) {
				_stream_ns.pause();
			} else {
				if (!playing) {
					_stream_ns.resume();
				}
			}
			super.pauseMedia(pPause);
		}
		
		private function onNetStatus(pEvent:NetStatusEvent):void {
			switch (pEvent.info.level) {
				case "error" :
					dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
					break;
				case "status" :
					switch (pEvent.info.code) {
						case "NetStream.Play.Start" :
							dispatchEvent(new Event(Event.INIT));
							break;
						case "NetStream.Play.Stop" :
							_videoEnded = true;
							break;
					}
					break;
			}
		}
		
		override protected function trackProgress(pEvent:Event):void {
			if (mediaPosition == mediaDuration || _videoEnded) {
				_videoEnded = false;
				stopMedia();
				dispatchEvent(new MediaEvent(MediaEvent.COMPLETE,mediaPosition, mediaDuration));
			}
			super.trackProgress(pEvent);
		}
		
		override public function get mediaPosition():Number {
			return _stream_ns.time;
		}
		
		override public function get media():Object {
			return _stream_ns;
		}
		
		override protected function applySoundTransform():void {
			_stream_ns.soundTransform = getSoundTransform();
		}

	}
}